package com.streetsmart;

/**
 * Set of all helper methods used across the application
 */
import java.io.IOException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Random;
import java.util.TimeZone;
import java.util.Vector;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.util.Log;

public class Utilities {
	public static ArrayList<Double> latitudeList = new ArrayList<Double>();
	public static ArrayList<Double> longitudeList = new ArrayList<Double>();
	private static final char[] symbols = new char[37];
	private static Calendar c = Calendar.getInstance();
	private static TimeZone tz = c.getTimeZone();
	private static BusSearch myYelp;
	private static String Consumer_Key, Consumer_Secret, Token, Token_Secret;
	private static ArrayList<ScheduleListItem> schedule = null;

	/**
	 * @return the schedule
	 */
	public static ArrayList<ScheduleListItem> getSchedule() {
		return schedule;
	}

	/**
	 * @param schedule
	 *            the schedule to set
	 */
	public static void setSchedule(ArrayList<ScheduleListItem> schedule) {
		Utilities.schedule = schedule;
	}

	/*
	 * // hashmaps with precomputed network calls public static HashMap<String,
	 * double[]> getLatAndLongMap; public static HashMap<String, String>
	 * getAddressMap; public static HashMap<String, String[]> getDistanceMap;
	 * public static HashMap<String, Vector<MyBusiness>>
	 * peekNearByBusinessesMap;
	 */
	static {
		for (int idx = 0; idx < 10; ++idx)
			symbols[idx] = (char) ('0' + idx);
		for (int idx = 10; idx < 36; ++idx)
			symbols[idx] = (char) ('a' + idx - 10);
		symbols[36] = '_';

		/*
		 * getLatAndLongMap = new HashMap<String, double[]>(); getAddressMap =
		 * new HashMap<String, String>(); getDistanceMap = new HashMap<String,
		 * String[]>(); peekNearByBusinessesMap = new HashMap<String,
		 * Vector<MyBusiness>>();
		 * 
		 * getLatAndLongMap.put("3600-3688 19th Ave, San Francisco, CA 94132, USA"
		 * , new double[]{37.72136080, -122.47504820}); //double latitute_sudha
		 * =
		 * getLatAndLongMap.get("3600-3688 19th Ave, San Francisco, CA 94132, USA"
		 * )[0];
		 * getLatAndLongMap.put("3577-3699 19th Ave, San Francisco, CA 94132, USA"
		 * , new double[]{37.72126410, -122.47534920});
		 * 
		 * getLatAndLongMap.put("1855 S Norfolk St, San Mateo, CA 94403, USA",
		 * new double[]{37.5548550, -122.29236680});
		 * getLatAndLongMap.put("3149 la selva circle, san mateo, ca", new
		 * double[]{37.54261140,-122.28410930}); getLatAndLongMap.put(
		 * "243-291 Winston Dr, Stonestown Galleria, San Francisco, CA 94132, USA"
		 * , new double[]{37.726896,-122.475682});
		 * 
		 * getAddressMap.put( makeLatLngKey(37.72136080, -122.47504820),
		 * "3600-3688 19th Ave, San Francisco, CA 94132, USA");
		 * getAddressMap.put(makeLatLngKey(37.72126410, -122.47534920),
		 * "3577-3699 19th Ave, San Francisco, CA 94132, USA");
		 * getAddressMap.put( makeLatLngKey(37.5548550, -122.29236680),
		 * "1855 S Norfolk St, San Mateo, CA 94403, USA");
		 * getAddressMap.put(makeLatLngKey(37.54261140, -122.28410930),
		 * "3149 la selva circle, san mateo, ca");
		 * getAddressMap.put(makeLatLngKey(37.726896, -122.475682),
		 * "243-291 Winston Dr, Stonestown Galleria, San Francisco, CA 94132, USA"
		 * );
		 * 
		 * getDistanceMap.put("3577-3699 19th Ave, San Francisco, CA 94132, USA, "
		 * + "3149 la selva circle, san mateo, ca", new String[]{"18.9654",
		 * "1517000", "Distance: 30.5 km Duration: 25 mins"});
		 * getDistanceMap.put
		 * ("3600-3688 19th Ave, San Francisco, CA 94132, USA, " +
		 * "1855 S Norfolk St, San Mateo, CA 94403, USA", new
		 * String[]{"18.053318", "1458000",
		 * "Distance: 29.1 km Durration: 24 mins"});
		 * getDistanceMap.put("3577-3699 19th Ave, San Francisco, CA 94132, USA, "
		 * + "1855 S Norfolk St, San Mateo, CA 94403, USA", new
		 * String[]{"18.053318", "1458000",
		 * "Distance: 29.1 km Durration: 24 mins"});
		 * getDistanceMap.put("1855 S Norfolk St, San Mateo, CA 94403, USA, "
		 * +"3149 la selva circle, san mateo, ca", new String[]{"1.0376899",
		 * "271000", "Distance: 1.7 km Durration: 5 mins"});
		 * getDistanceMap.put("3149 la selva circle, san mateo, ca, " +
		 * "3577-3699 19th Ave, San Francisco, CA 94132, USA", new
		 * String[]{"18.9654", "1517000",
		 * "Distance: 30.5 km Duration: 25 mins"});
		 * getDistanceMap.put("3149 la selva circle, san mateo, ca, " +
		 * "243-291 Winston Dr, Stonestown Galleria, San Francisco, CA 94132, USA"
		 * , new String[]{"19.37187", "1528000",
		 * "Distance: 31.2 km Durration: 25 mins"} ); getDistanceMap.put(
		 * "243-291 Winston Dr, Stonestown Galleria, San Francisco, CA 94132, USA, "
		 * +"3600-3688 19th Ave, San Francisco, CA 94132, USA", new
		 * String[]{"0.44117355", "80000", "Distance: 0.7 km Durration: 1 min"}
		 * ); getDistanceMap.put(
		 * "243-291 Winston Dr, Stonestown Galleria, San Francisco, CA 94132, USA, "
		 * +"3577-3699 19th Ave, San Francisco, CA 94132, USA", new
		 * String[]{"0.44117355", "80000", "Distance: 0.7 km Durration: 1 min"}
		 * );
		 * 
		 * Vector<MyBusiness> result1 = new Vector<MyBusiness>(); MyLocation
		 * loc1 = new MyLocation(37.5548550, -122.29236680,
		 * "1855 S Norfolk St, San Mateo, CA 94403, USA"); MyBusiness bus1 = new
		 * MyBusiness(loc1.getAddress(), loc1);
		 * bus1.setDistanceToIntendedDestination(1.0376899f); result1.add(bus1);
		 * peekNearByBusinessesMap.put("3149 la selva circle, san mateo, ca",
		 * result1);
		 * 
		 * Vector<MyBusiness> result2 = new Vector<MyBusiness>(); MyLocation
		 * loc2 = new MyLocation(37.726896,-122.475682,
		 * "243-291 Winston Dr, Stonestown Galleria, San Francisco, CA 94132, USA"
		 * ); MyBusiness bus2 = new MyBusiness(loc2.getAddress(), loc2);
		 * bus2.setDistanceToIntendedDestination(0.44117355f);
		 * result2.add(bus2); peekNearByBusinessesMap.put(
		 * "3600-3688 19th Ave, San Francisco, CA 94132, USA", result2);
		 * 
		 * 
		 * Vector<MyBusiness> result3 = new Vector<MyBusiness>(); MyLocation
		 * loc3 = new MyLocation(37.726896,-122.475682,
		 * "243-291 Winston Dr, Stonestown Galleria, San Francisco, CA 94132, USA"
		 * ); MyBusiness bus3 = new MyBusiness(loc3.getAddress(), loc3);
		 * bus3.setDistanceToIntendedDestination(0.44117355f);
		 * result3.add(bus3); peekNearByBusinessesMap.put(
		 * "3577-3699 19th Ave, San Francisco, CA 94132, USA", result3);
		 * 
		 * getLatAndLongMap.put("3149 la selva circle, san mateo, ca", new
		 * double[]{37.5426114,-122.2841093});
		 * getLatAndLongMap.put("1412 market street, san francisco, ca", new
		 * double[]{37.7762896,-122.4181504} );
		 * 
		 * getAddressMap.put(new double[]{37.519431,-122.27728},
		 * "968 Ralston Ave, Belmont, CA 94002, USA"); getAddressMap.put(new
		 * double[]{37.512569,-122.293035},
		 * "1910 Ralston Ave, Belmont, CA 94002, USA"); getAddressMap.put(new
		 * double[]{37.54494,-122.305326},
		 * "17 E 25th Ave, San Mateo, CA 94403, USA"); getAddressMap.put(new
		 * double[]{37.560089,-122.280855},
		 * "2270 Bridgepointe Pkwy, Bridgepointe Shopping Center, Foster City, CA 94404, USA"
		 * ); getAddressMap.put(new double[]{37.533972,-122.293797},
		 * "3799 State Highway 82, San Mateo, CA 94403, USA");
		 * getAddressMap.put(new double[]{37.516276,-122.271106},
		 * "1500 El Camino Real, Belmont, CA 94070, USA"); getAddressMap.put(new
		 * double[]{37.560802,-122.273958},
		 * "1000 Metro Center Blvd, Foster City, CA 94404, USA");
		 * getAddressMap.put(new double[]{37.51978,-122.251756},
		 * "200 Redwood Shores Pkwy, Redwood City, CA 94065, USA");
		 * getAddressMap.put(new double[]{37.527258,-122.286401},
		 * "815 Belmont Ave, Belmont, CA 94002, USA"); getAddressMap.put(new
		 * double[]{37.549418,-122.264668},
		 * "1064 Shell Blvd, Charter Square Shopping Center, Foster City, CA 94404, USA"
		 * ); getAddressMap.put(new double[]{37.554569,-122.302007},
		 * "1803-1825 S Grant St, San Mateo, CA 94402, USA");
		 * getAddressMap.put(new double[]{37.544636,-122.292023},
		 * "1010 Park Pl, San Mateo, CA 94403, USA"); getAddressMap.put(new
		 * double[]{37.56152,-122.274878},
		 * "1001 Metro Center Blvd, Foster City, CA 94404, USA");
		 * getAddressMap.put(new double[]{37.553616,-122.257095},
		 * "1060 Foster City Blvd, San Mateo, CA 94404, USA");
		 * getAddressMap.put(new double[]{37.548406,-122.311172},
		 * "62-120 W 20th Ave, San Mateo, CA 94403, USA"); getAddressMap.put(new
		 * double[]{37.523201,-122.252051},
		 * "270 Redwood Shores Pkwy, Redwood City, CA 94065, USA");
		 * getAddressMap.put(new double[]{37.553611,-122.26367},
		 * "900 Corsair Ln, Foster City, CA 94404, USA"); getAddressMap.put(new
		 * double[]{37.520239,-122.276983},
		 * "Flasner Ln, Belmont, CA 94002, USA"); getAddressMap.put(new
		 * double[]{37.512254,-122.295465},
		 * "2100 Ralston Ave, Belmont, CA 94002, USA"); getAddressMap.put(new
		 * double[]{37.544254,-122.284441},
		 * "3016-3080 La Selva St, San Mateo, CA 94403, USA");
		 * getAddressMap.put(new double[]{37.536498,-122.298396},
		 * "18-42 W Hillsdale Blvd, San Mateo, CA 94403, USA");
		 * getAddressMap.put(new double[]{37.53395,-122.295263},
		 * "25 37th Ave, San Mateo, CA 94403, USA"); getAddressMap.put(new
		 * double[]{37.529296,-122.290063},
		 * "49 42nd Ave, San Mateo, CA 94403, USA"); getAddressMap.put(new
		 * double[]{37.540935,-122.291351},
		 * "Pike Ln, San Mateo, CA 94403, USA"); getAddressMap.put(new
		 * double[]{37.566884,-122.320829},
		 * "221 S Claremont St, San Mateo, CA 94401, USA");
		 * getAddressMap.put(new double[]{37.526526,-122.283669},
		 * "3-171 Davey Glen Rd, Belmont, CA 94002, USA"); getAddressMap.put(new
		 * double[]{37.554725,-122.303147},
		 * "678 Concar Dr, San Mateo Commons Shopping Center, San Mateo, CA 94402, USA"
		 * ); getAddressMap.put(new double[]{37.545334,-122.271212},
		 * "919 Edgewater Blvd, Edgewater Place Shopping Center, Foster City, CA 94404, USA"
		 * ); getAddressMap.put(new double[]{37.530334,-122.287645},
		 * "35 Laurie Meadows Dr, San Mateo, CA 94403, USA");
		 * getAddressMap.put(new double[]{37.522525,-122.251697},
		 * "240 Redwood Shores Pkwy, Redwood City, CA 94065, USA");
		 * getAddressMap.put(new double[]{37.700015,-122.482262},
		 * "451 Westlake Center, Westlake Shopping Center, Daly City, CA 94015, USA"
		 * ); getAddressMap.put(new double[]{37.743236,-122.473957},
		 * "730 Taraval St, San Francisco, CA 94116, USA");
		 * getAddressMap.put(new double[]{37.71966,-122.439188},
		 * "4950 Mission St, San Francisco, CA 94112, USA");
		 * getAddressMap.put(new double[]{37.731402,-122.450063},
		 * "635-663 Monterey Blvd, San Francisco, CA 94127, USA");
		 * getAddressMap.put(new double[]{37.726896,-122.475682},
		 * "243-291 Winston Dr, Stonestown Galleria, San Francisco, CA 94132, USA"
		 * ); getAddressMap.put(new double[]{37.733149,-122.489673},
		 * "Havenside Dr, San Francisco, CA 94132, USA"); getAddressMap.put(new
		 * double[]{37.726838,-122.441368},
		 * "551-599 San Juan Ave, San Francisco, CA 94112, USA");
		 * getAddressMap.put(new double[]{37.744912,-122.45239},
		 * "635 Portola Dr, San Francisco, CA 94127, USA");
		 * getAddressMap.put(new double[]{37.694488,-122.471356},
		 * "2346 Junipero Serra Blvd, Broadmoor Bicycle Shop, Daly City, CA 94015, USA"
		 * ); getAddressMap.put(new double[]{37.69945,-122.481657},
		 * "601 Westlake Center, Westlake Shopping Center, Daly City, CA 94015, USA"
		 * ); getAddressMap.put(new double[]{37.697769,-122.463039},
		 * "6843 Mission St, Daly City, CA 94014, USA"); getAddressMap.put(new
		 * double[]{37.742529,-122.490035},
		 * "2226 Taraval St, San Francisco, CA 94116, USA");
		 * getAddressMap.put(new double[]{37.711867,-122.452814},
		 * "2950-2998 Alemany Blvd, San Francisco, CA 94112, USA");
		 * getAddressMap.put(new double[]{37.743086,-122.472356},
		 * "2416 16th Ave, San Francisco, CA 94116, USA"); getAddressMap.put(new
		 * double[]{37.710417,-122.467703},
		 * "3995 Alemany Blvd, San Francisco, CA 94132, USA");
		 * getAddressMap.put(new double[]{37.744918,-122.452548},
		 * "667 Portola Dr, San Francisco, CA 94127, USA");
		 * getAddressMap.put(new double[]{37.72436,-122.458941},
		 * "1537 Ocean Ave, San Francisco, CA 94112, USA");
		 * getAddressMap.put(new double[]{37.735591,-122.50189},
		 * "2560 Sloat Blvd, San Francisco, CA 94116, USA");
		 * getAddressMap.put(new double[]{37.717012,-122.474157},
		 * "109-117 Cambon Dr, San Francisco, CA 94132, USA");
		 * getAddressMap.put(new double[]{37.693145,-122.475187},
		 * "365 87th St, Daly City, CA 94015, USA");
		 * 
		 * 
		 * 
		 * 
		 * 
		 * //getAddressMap.put(new double[]{1.2,1.3}, "imaginary location");
		 * //getDistanceMap.put(new String[]{"bla","bla"}, new
		 * String[]{"bla","bla"}); //pebekNearByBusinessesMap.put(String
		 * address, Vector<MyBusiness>);
		 */

	}
	private static final char[] buf = new char[5];
	private static Random random = new Random();

	public Utilities(Context c) {
		Consumer_Key = c.getString(R.string.Consumer_Key);
		Consumer_Secret = c.getString(R.string.Consumer_Secret);
		Token = c.getString(R.string.Token);
		Token_Secret = c.getString(R.string.Token_Secret);
		myYelp = new BusSearch(Consumer_Key, Consumer_Secret, Token,
				Token_Secret);
	}

	public static String nextRandomString() {
		// http://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string-in-java
		for (int idx = 0; idx < buf.length; ++idx)
			buf[idx] = symbols[random.nextInt(symbols.length)];
		return new String(buf);
	}

	/**
	 * to generate uniform precision lat and lng for comparing in test cases
	 * 
	 * @param lat
	 * @param lng
	 * @return
	 */
	public static String makeLatLngKey(double lat, double lng) {
		double latStr = (double) Math.round(lat * 100000) / 100000;
		double lngStr = (double) Math.round(lng * 100000) / 100000;
		return ("" + latStr + ", " + lngStr);
	}

	/**
	 * converts the given geo points into same precision and then compare both
	 * 
	 * @param src
	 * @param dest
	 * @return
	 */
	public static int compareGeoPoint(double src, double dest) {
		double source = (double) Math.round(src * 100000) / 100000;
		double destination = (double) Math.round(dest * 100000) / 100000;
		return Double.compare(source, destination);
	}

	public static void clearGeopoints() {
		latitudeList.clear();
		longitudeList.clear();
	}

	/**
	 * Given a string address identifies the latitude and longitude of the same
	 * using Google geocoding api
	 * 
	 * @param address
	 * @return
	 * @throws JSONException
	 */
	public static double[] getLatAndLng(String address) throws JSONException {

		/*
		 * if (getLatAndLongMap.containsKey(address)) return
		 * getLatAndLongMap.get(address);
		 */
		String URL = "http://maps.googleapis.com/maps/api/geocode/json?address=";
		String result = "";
		double[] geocodes = new double[2];
		HttpClient httpclient = new DefaultHttpClient();
		HttpGet request = new HttpGet(URL + URLEncoder.encode(address)
				+ "&sensor=false");
		ResponseHandler<String> handler = new BasicResponseHandler();
		try {
			result = httpclient.execute(request, handler);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		httpclient.getConnectionManager().shutdown();
		JSONObject obj = new JSONObject(result);
		if ((obj.getString("status")).equals("OK")) {
			JSONArray array = obj.getJSONArray("results");
			JSONObject firstElement = array.getJSONObject(0);
			JSONObject geometry = firstElement.getJSONObject("geometry");
			JSONObject location = geometry.getJSONObject("location");
			geocodes[0] = location.getDouble("lat");
			geocodes[1] = location.getDouble("lng");
		}
		// getLatAndLongMap.put(address, geocodes);
		// Log.d("getgeocode", "getLatAndLongMap.put(" + address + ", " +
		// "new double[]{" +geocodes[0] + "," + geocodes[1] +"});");
		return geocodes;
	}

	/**
	 * given latitude and longitude of a location , fetches the address using
	 * the google reverse geocoding api.
	 * 
	 * @param geocodes
	 * @return
	 * @throws JSONException
	 */
	public static String getAddress(double[] geocodes) throws JSONException {
		/*
		 * String input = makeLatLngKey(geocodes[0], geocodes[1]); if
		 * (getAddressMap.containsKey(input)) return getAddressMap.get(input);
		 */

		String URL = "http://maps.googleapis.com/maps/api/geocode/json?latlng=";
		String result = "";
		String address = "";
		HttpClient httpclient = new DefaultHttpClient();
		HttpGet request = new HttpGet(URL + geocodes[0] + "," + geocodes[1]
				+ "&sensor=false");
		ResponseHandler<String> handler = new BasicResponseHandler();
		try {
			result = httpclient.execute(request, handler);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		httpclient.getConnectionManager().shutdown();
		JSONObject obj = new JSONObject(result);
		if ((obj.getString("status")).equals("OK")) {
			JSONArray array = obj.getJSONArray("results");
			JSONObject firstElement = array.getJSONObject(0);
			address = firstElement.getString("formatted_address");
		}
		// getAddressMap.put(geocodes, address);
		// Log.d("getaddress ", "getAddressMap.put(new double[]{" + geocodes[0]
		// + "," + geocodes[1] +"}, " +address +")" );
		return address;
	}

	/**
	 * get distance between two locations by using the google distance matrix
	 * api
	 * 
	 * @param source
	 * @param destination
	 * @return
	 * @throws JSONException
	 */
	public static String[] getDistance(MyLocation source, MyLocation destination)
			throws JSONException {
		/*
		 * String input = source + ", " + destination; if
		 * (getDistanceMap.containsKey(input)) return getDistanceMap.get(input);
		 */

		// TODO change the argument type to event and get coordinates from event
		// object.
		// TODO also chagne the return type to a location object as needed
		// consider chagning the String address to geo codes before placing
		// request as Distance matrix internally calls geocode API.
		String URL = "http://maps.googleapis.com/maps/api/distancematrix/json?origins=";
		String result = "";
		String[] resultArray = new String[3];
		String distanceStr = "", durationStr = "";
		HttpClient httpclient = new DefaultHttpClient();
		HttpGet request = new HttpGet(URL + source.getLatitude() + ","
				+ source.getLongitude()
				+ // URLEncoder.encode(source)
				"&destinations=" + destination.getLatitude() + ","
				+ destination.getLongitude()// URLEncoder.encode(destination)
				+ "&sensor=true");
		ResponseHandler<String> handler = new BasicResponseHandler();
		try {
			result = httpclient.execute(request, handler);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		httpclient.getConnectionManager().shutdown();
		JSONObject obj = new JSONObject(result);
		if ((obj.getString("status")).equals("OK")) {
			JSONArray array = obj.getJSONArray("rows");
			JSONObject obj1 = array.getJSONObject(0);
			array = obj1.getJSONArray("elements");
			obj1 = array.getJSONObject(0);
			distanceStr = (obj1.getJSONObject("distance")).getString("text");
			resultArray[0] = (obj1.getJSONObject("distance"))
					.getString("value");
			resultArray[0] = String.valueOf(convertToMiles(Long
					.parseLong(resultArray[0])));
			durationStr = (obj1.getJSONObject("duration")).getString("text");
			resultArray[1] = (obj1.getJSONObject("duration"))
					.getString("value");
			resultArray[1] = String
					.valueOf(Long.parseLong(resultArray[1]) * 1000);
		}
		resultArray[2] = "Distance: " + distanceStr + "\n" + "Durration: "
				+ durationStr;

		// getDistanceMap.put(input, resultArray);
		// Log.d("getdistance", "getDistanceMap.put(" + "new String[]{" +
		// input[0] + ", " + input[1] + "}, " + "new String[]{" + resultArray[0]
		// +", " + resultArray[1] + ", " + resultArray[2] +"});");
		// Log.d("get distance for the source " + source + " and " +
		// destination, ""+ resultArray[0] +",  " + resultArray[1] + ",   " +
		// resultArray[2]);
		return resultArray;
	}

	/**
	 * get distance between two pair of geopoints(coordinates) by using the
	 * google distance matrix api
	 * 
	 * @param source
	 * @param destination
	 * @return
	 * @throws JSONException
	 */
	public static String[] getDistance(double[] source, double[] destination)
			throws JSONException {
		String URL = "http://maps.googleapis.com/maps/api/distancematrix/json?origins=";
		String result = "";
		String[] resultArray = new String[3];
		String distanceStr = "", durationStr = "";
		HttpClient httpclient = new DefaultHttpClient();
		HttpGet request = new HttpGet(URL + source[0] + "," + source[1] + // URLEncoder.encode(source)
				"&destinations=" + destination[0] + "," + destination[1]// URLEncoder.encode(destination)
				+ "&sensor=true");
		ResponseHandler<String> handler = new BasicResponseHandler();
		try {
			result = httpclient.execute(request, handler);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		httpclient.getConnectionManager().shutdown();
		JSONObject obj = new JSONObject(result);
		if ((obj.getString("status")).equals("OK")) {
			JSONArray array = obj.getJSONArray("rows");
			JSONObject obj1 = array.getJSONObject(0);
			array = obj1.getJSONArray("elements");
			obj1 = array.getJSONObject(0);
			distanceStr = (obj1.getJSONObject("distance")).getString("text");
			resultArray[0] = (obj1.getJSONObject("distance"))
					.getString("value");
			resultArray[0] = String.valueOf(convertToMiles(Long
					.parseLong(resultArray[0])));
			durationStr = (obj1.getJSONObject("duration")).getString("text");
			resultArray[1] = (obj1.getJSONObject("duration"))
					.getString("value");
			resultArray[1] = String
					.valueOf(Long.parseLong(resultArray[1]) * 1000);
		}
		resultArray[2] = "Distance: " + distanceStr + "\n" + "Durration: "
				+ durationStr;

		return resultArray;
	}

	public static float convertToMiles(long metres) {
		return 0.621371192f * metres / 1000;
	}

	/**
	 * look up businesses near a geo point in certain radius. uses google places
	 * api
	 * 
	 * @param loc
	 * @param radius
	 * @param types
	 * @return
	 * @throws JSONException
	 */
	public static Vector<MyBusiness> peekNearByBusinesses(MyLocation loc,
			float radius, Vector<String> types) throws JSONException {
		/*
		 * if(peekNearByBusinessesMap.containsKey(loc.getAddress())){ return
		 * peekNearByBusinessesMap.get(loc.getAddress()); }
		 */

		String name;
		MyLocation BusinessLocation;
		Vector<String> category = new Vector<String>();
		MyBusiness Source = new MyBusiness(loc.getAddress(), loc);
		float appxDistanceFromSource = radius;
		Vector<MyBusiness> BusinessList = new Vector<MyBusiness>();
		String URL = "https://maps.googleapis.com/maps/api/place/search/json?location=";
		String result = "";
		HttpClient httpclient = new DefaultHttpClient();
		URL += loc.getLatitude() + "," + loc.getLongitude();
		URL += "&radius=" + radius;
		String type;
		StringBuilder temp = new StringBuilder();
		temp.append(types.get(0));
		for (int i = 1; i < types.size(); i++) {
			temp.append("|");
			temp.append(types.get(i));
		}
		type = temp.toString();
		URL += "&types=" + type;
		URL += "&sensor=true";
		URL += "&key=AIzaSyAzKZWP0TWKRxqKC0ybVOp295EGl2Vb3W0";
		HttpGet request = new HttpGet(URL);
		ResponseHandler<String> handler = new BasicResponseHandler();
		try {
			result = httpclient.execute(request, handler);
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		httpclient.getConnectionManager().shutdown();
		JSONObject obj = new JSONObject(result);
		if ((obj.getString("status")).equals("OK")) {
			JSONArray array = obj.getJSONArray("results");
			int count = array.length();
			for (int i = 0; i < count; i++) {
				JSONObject item = array.getJSONObject(i);
				JSONObject geometry = item.getJSONObject("geometry");
				JSONObject geo_Location = geometry.getJSONObject("location");
				Double lat = geo_Location.getDouble("lat");
				Double lng = geo_Location.getDouble("lng");
				BusinessLocation = new MyLocation(lat, lng);
				name = item.getString("name");
				JSONArray categoryList = item.getJSONArray("types");
				category.clear();
				for (int cnt = 0; cnt < categoryList.length(); cnt++) {
					category.add(categoryList.getString(cnt));
				}
				MyBusiness busObject = new MyBusiness(name, BusinessLocation,
						category, Source, appxDistanceFromSource);
				BusinessList.add(busObject);

				Log.d("locationofbusiness",
						"new MyLocation(" + loc.getLatitude() + ","
								+ loc.getLongitude() + "," + loc.getAddress()
								+ ");");
				Log.d("locationofbusiness",
						"" + busObject.getTimeToreachIntendedDestination());
			}
		}

		// peekNearByBusinessesMap.put(loc.getAddress(), BusinessList);

		// Log.d("List of businesses near the address" + loc.getAddress(),
		// "BusinessList");
		return BusinessList;
	}

	/**
	 * 
	 * look up businesses near a geo point in certain radius. uses yelp search
	 * api
	 * 
	 * @param locName
	 * @param loc
	 * @param radius
	 * @param type
	 * @param categories
	 * @return
	 * @throws JSONException
	 */
	public static Vector<MyBusiness> peekNearByBusinessesYelp(String locName,
			MyLocation loc, float radius, String type, String categories)
			throws JSONException {

		String name = "";
		String id = "";
		String imgUrl = "";
		float rating = 2.5f;
		String temp = "";
		MyLocation BusinessLocation;
		Vector<String> category = new Vector<String>();
		MyBusiness Source = new MyBusiness(locName, loc);
		float appxDistanceFromSource = radius;
		Vector<MyBusiness> BusinessList = new Vector<MyBusiness>();
		String result = myYelp.search(type, loc, categories);
		JSONObject item;
		JSONObject location;
		JSONArray addr;
		JSONArray catg;
		JSONArray tmp;
		MyBusiness busObject;
		try {
			JSONObject response = new JSONObject(result);
			if (response.has("businesses")) {
				JSONArray arrayOfBusinesses = response
						.getJSONArray("businesses");
				for (int i = 0; i < arrayOfBusinesses.length(); i++) {
					item = arrayOfBusinesses.getJSONObject(i);
					id = item.getString("id");
					name = item.getString("name");
					try {
						imgUrl = item.getString("image_url");
					} catch (JSONException e) {
						imgUrl = "building";
					}
					rating = (float) item.getDouble("rating");
					temp = "";
					location = item.getJSONObject("location");
					addr = location.getJSONArray("address");
					temp += addr.getString(0);
					for (int cnt = 1; cnt < addr.length(); cnt++) {
						temp += ", " + addr.getString(cnt);
					}
					temp += ", " + location.getString("city") + ", ";
					temp += location.getString("state_code") + " ";
					temp += location.getString("postal_code");
					JSONObject coord = location.getJSONObject("coordinate");
					Double lat = coord.getDouble("latitude");
					Double lng = coord.getDouble("longitude");
					BusinessLocation = new MyLocation(lat, lng, temp);
					appxDistanceFromSource = 0.000621371192f * item
							.getInt("distance");
					category.clear();
					// category.add(type);
					catg = item.getJSONArray("categories");
					tmp = catg.getJSONArray(0);
					category.add(tmp.getString(0));
					int cnt = 0;
					do {
						for (int j = 1; j < tmp.length(); j++) {
							category.add(tmp.getString(j));
						}
						cnt++;
						if (cnt < catg.length()) {
							tmp = catg.getJSONArray(cnt);
							category.add(tmp.getString(0));
						}
					} while (cnt < catg.length());
					busObject = new MyBusiness(name, id, imgUrl, rating,
							BusinessLocation, category, Source,
							appxDistanceFromSource);
					String[] timetoDestination = getDistance(
							new double[] { BusinessLocation.getLatitude(),
									BusinessLocation.getLongitude() },
							new double[] { loc.getLatitude(),
									loc.getLongitude() });
					busObject.setTimeToreachIntendedDestination(Long
							.parseLong(timetoDestination[1]));
					BusinessList.add(busObject);
				}
			}
		} catch (JSONException e) {
			return null;
		}
		return BusinessList;
	}

	public static long getCurrentTime() {
		c = Calendar.getInstance();
		return c.getTimeInMillis();
	}

	public static boolean currentTimeIsNotNight() {
		c = Calendar.getInstance();
		int hour = c.get(Calendar.HOUR_OF_DAY);
		if ((hour >= 8) && (hour <= 20))
			return true;
		return false;
	}

	public static Date getDate(String mdy) throws ParseException {
		SimpleDateFormat simpleDate = new SimpleDateFormat("MM/dd/yyyy");
		simpleDate.setTimeZone(tz);
		Date result = simpleDate.parse(mdy);

		return result;
	}

	public static long getTimeStamp(Date dateobj) {
		return dateobj.getTime();
	}

	public static long getTodaysTimeStamp() {
		c = Calendar.getInstance();
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);
		Log.d("UTILITIES", "" + c.getTimeInMillis());
		return (c.getTimeInMillis());
	}

	public static long getTomorrowsTimeStamp() {
		c = Calendar.getInstance();
		c.add(Calendar.DAY_OF_YEAR, 1);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		return (c.getTimeInMillis());
	}

	public static long getDayAfterTomorrowsTimeStamp() {
		c = Calendar.getInstance();
		c.add(Calendar.DAY_OF_YEAR, 2);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		return (c.getTimeInMillis());
	}

	public static long getCurrentWeeksTimeStamp() {
		c = Calendar.getInstance();
		c.clear(Calendar.HOUR_OF_DAY);
		c.clear(Calendar.MINUTE);
		c.clear(Calendar.SECOND);
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		return (c.getTimeInMillis());
	}

	public static long getNextWeeksTimeStamp() {
		c = Calendar.getInstance();
		c.clear(Calendar.HOUR_OF_DAY);
		c.clear(Calendar.MINUTE);
		c.clear(Calendar.SECOND);
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.add(Calendar.WEEK_OF_YEAR, 1);
		return (c.getTimeInMillis());
	}

	public static long getNextNextWeeksTimeStamp() {
		c = Calendar.getInstance();
		c.clear(Calendar.HOUR_OF_DAY);
		c.clear(Calendar.MINUTE);
		c.clear(Calendar.SECOND);
		c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.add(Calendar.WEEK_OF_YEAR, 2);
		return (c.getTimeInMillis());
	}

	public static long convertHourstoMillis(float hour) {
		int hr = (int) hour;
		int mins = (int) (60 * (hour - hr));
		return (((hr * 60) + mins) * 60 * 1000);
	}

	public static Date convertMillistoDate(long millis) {
		c = Calendar.getInstance();
		c.setTimeInMillis(millis);
		return c.getTime();
	}

}